package com.zhou.framework.mail;


import com.zhou.util.ObjectUtil;
import com.zhou.util.StringTool;
import com.zhou.util.tag.Tag;
import com.zhou.message.dao.Attachment;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.util.ByteArrayDataSource;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

/**
 * @author lang.zhou
 * @date 2019/12/11
 */
public class MailUtil {

    /**
     * 邮件发送的方法
     * @return 成功或失败
     */
    public static void send(MailServerConfig config, MailMessage mailMessage) throws Exception {
        /* 主题*/
        String title = mailMessage.getTitle();
        /* 内容*/
        String content = mailMessage.getContent();
        String contentType = mailMessage.getContentType();
        if(StringTool.isEmpty(contentType)){
            contentType = "text/html;charset=UTF-8";
        }
        /* 协议*/
        String smtp = config.getProtocol();
        if(StringTool.isEmpty(smtp)){
            smtp = "smtp";
        }
        /* 发送服务器服务器*/
        String host = config.getServer();
        /* 邮件发送人*/
        String sendAddress = config.getSendAddress();
        /* 邮件发送人端口*/
        int sendPort = config.getPort();

        /* 邮件发送人密码*/
        String userPwd = config.getPassword();
        if(ObjectUtil.hasEmpty(host,sendAddress,userPwd)){
            throw new RuntimeException("邮箱服务器配置不完整！");
        }
        List<MailReceiver> addressList = mailMessage.getReceiverList();
        List<MailReceiver> duplicateList = mailMessage.getDuplicateList();
        List<Attachment> attachmentList = mailMessage.getAttachmentList();
        if(ObjectUtil.allEmpty(addressList,duplicateList)){
            return;
        }
        // 第一步：创建Session
        Properties props = new Properties();
        // 指定邮件的传输协议，smtp(Simple Mail Transfer Protocol 简单的邮件传输协议)
        props.put("mail.transport.protocol", smtp);
        // 指定邮件发送服务器服务器 "smtp.qq.com"
        props.put("mail.host", host);
        props.put("mail.port", sendPort);
        props.put("mail.smtp.port", sendPort);
        props.put("mail.smtp.auth", "true");
        if(465 == sendPort){
            props.put("mail.smtp.ssl.enable", true);
        }
        // 指定邮件的发送人(您用来发送邮件的服务器，比如您的163\sina等邮箱)
        props.put("mail.from", sendAddress);
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.socketFactory.fallback", "false");
        props.put("mail.smtp.socketFactory.port", sendPort);
        //Session session = Session.getDefaultInstance(props);
        Session session = Session.getInstance(props);

        // 开启调试模式
        session.setDebug(config.isDebug());
        Transport transport = null;
        try {
            // 第二步：获取邮件发送对象
            transport = session.getTransport();
            //System.out.println("连接邮件服务器...");
            // 连接邮件服务器，链接您的163、sina邮箱，用户名（不带@163.com，登录邮箱的邮箱账号，不是邮箱地址）、密码
            transport.connect(sendAddress, userPwd);


            Multipart multipart = null;
            boolean hasAttachment = false;
            if(attachmentList != null && attachmentList.size() > 0){
                hasAttachment = true;
                multipart = new MimeMultipart();
                //邮件正文
                BodyPart bodyPart = new MimeBodyPart();
                bodyPart.setContent(content, contentType);
                multipart.addBodyPart(bodyPart);
                for(Attachment attachment : attachmentList) {
                    BodyPart attachmentPart = new MimeBodyPart();
                    //DataSource source = new FileDataSource(attachment);
                    String cp = ContentTypeMap.getContentType(attachment.getPrefix());
                    attachmentPart.addHeader("Content-Type", cp);

                    DataSource source = new ByteArrayDataSource(attachment.getFile(),cp);
                    attachmentPart.setDataHandler(new DataHandler(source));
                    //避免中文乱码的处理
                    attachmentPart.setFileName(MimeUtility.encodeWord(attachment.getFileName()));
                    multipart.addBodyPart(attachmentPart);
                }
            }
            // 第三步：创建邮件消息体
            MimeMessage message = new MimeMessage(session);
            //设置自定义发件人昵称
            String nick="";
            try {
                nick = MimeUtility.encodeText(StringTool.safeToString(config.getSendName(),config.getSendAddress()));
            } catch (Exception e) {
                e.printStackTrace();
            }
            //设置发信人
            message.setFrom(new InternetAddress(nick+" <"+sendAddress+">"));

            // 邮件的主题
            message.setSubject(title);
            List<Address> receiverList = new ArrayList<>();
            /* 收件人*/

            if(addressList != null && addressList.size() > 0){
                for (MailReceiver r : addressList) {
                    String address = r.getAddress();
                    if (StringTool.isNotEmpty(address)) {
                        Address toAddress = new InternetAddress(address);
                        receiverList.add(toAddress);
                        message.addRecipient(Message.RecipientType.TO, toAddress);
                    }
                }

            }
            /* 抄送人*/
            if(duplicateList != null && duplicateList.size() > 0){

                for (MailReceiver r : duplicateList) {
                    String address = r.getAddress();

                    if (StringTool.isNotEmpty(address)) {
                        Address toAddress = new InternetAddress(address);
                        receiverList.add(toAddress);
                        message.addRecipient(Message.RecipientType.CC, toAddress);
                    }
                }
            }

            // 邮件发送时间
            message.setSentDate(new Date());
            // 邮件的内容
            if(hasAttachment){
                message.setContent(multipart);
                message.saveChanges();
            }else{
                message.setContent(content, contentType);
            }
            Address[] finalReceiver = new Address[receiverList.size()];
            for(int i=0;i<receiverList.size();i++){
                finalReceiver[i] = receiverList.get(i);
            }
            // 第四步：发送邮件
            // 第一个参数：邮件的消息体
            // 第二个参数：邮件的接收人，多个接收人用逗号隔开（test1@163.com,test2@sina.com）
            transport.sendMessage(message, finalReceiver);
            //System.out.println("发送邮件完成！");
        }finally {
            if(transport != null){
                try {
                    transport.close();
                    //System.out.println("连接已关闭！");
                } catch (MessagingException e) {
                    //ignore
                }
            }

        }
    }

    public static void main(String[] args) throws Exception {
        MailServerConfig config = new MailServerConfig();
        //config.setServer("smtp.qq.com");
        config.setServer("mail.sinitek.com");

        //config.setPassword("zhoulang"+入职日期);
        config.setSendAddress("lang.zhou2@sinitek.com");
        config.setSendName("不恋水的鱼");
        MailMessage message = new MailMessage("标题"+new Date(),new Tag("b").append("内容"));
        //message.setReceiverList(Collections.singletonList("zhoulang1996@qq.com"));
        MailReceiver receiver = new MailReceiver("lang.zhou2@sinitek.com");
        message.addDuplicate(receiver);
        File file = new File("C:\\Users\\Administrator\\Desktop\\telnet发邮件.txt");
        Attachment a = new Attachment();
        a.setFileName(file.getName());
        a.setFile(file);
        message.addAttachement(a);
        // 您要发送给谁，标题，内容
        MailUtil.send(config, message);
    }
}
